home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / modes / prolog.el.z / prolog.el
Encoding:
Text File  |  1998-05-21  |  10.9 KB  |  333 lines

  1. ;;; prolog.el --- major mode for editing and running Prolog under Emacs
  2.  
  3. ;; Copyright (C) 1986, 1987, 1993 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
  6. ;; Keywords: languages
  7.  
  8. ;; This file is part of XEmacs.
  9.  
  10. ;; XEmacs is free software; you can redistribute it and/or modify it
  11. ;; under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; XEmacs is distributed in the hope that it will be useful, but
  16. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. ;; General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with XEmacs; see the file COPYING.  If not, write to the 
  22. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. ;; Boston, MA 02111-1307, USA.
  24.  
  25. ;;; Synched up with: Not synched with FSF, we appear to have a newer version
  26.  
  27. ;;; Commentary:
  28.  
  29. ;; This package provides a major mode for editing Prolog.  It knows
  30. ;; about Prolog syntax and comments, and can send regions to an inferior
  31. ;; Prolog interpreter process.
  32.  
  33. ;;; Code:
  34.  
  35. (defvar prolog-mode-syntax-table nil)
  36. (defvar prolog-mode-abbrev-table nil)
  37. (defvar prolog-mode-map nil)
  38.  
  39. (defgroup prolog nil
  40.   "Major mode for editing and running Prolog under Emacs"
  41.   :group 'languages)
  42.  
  43.   
  44. (defcustom prolog-program-name "prolog"
  45.   "*Program name for invoking an inferior Prolog with `run-prolog'."
  46.   :type 'string
  47.   :group 'prolog)
  48.  
  49. (defcustom prolog-consult-string "reconsult(user).\n"
  50.   "*(Re)Consult mode (for C-Prolog and Quintus Prolog). "
  51.   :type 'string
  52.   :group 'prolog)
  53.  
  54. (defcustom prolog-compile-string "compile(user).\n"
  55.   "*Compile mode (for Quintus Prolog)."
  56.   :type 'string
  57.   :group 'prolog)
  58.  
  59. (defcustom prolog-eof-string "end_of_file.\n"
  60.   "*String that represents end of file for prolog.
  61. nil means send actual operating system end of file."
  62.   :type 'string
  63.   :group 'prolog)
  64.  
  65. (defcustom prolog-indent-width 4
  66.   "Level of indentation in Prolog buffers."
  67.   :type 'integer
  68.   :group 'prolog)
  69.  
  70. (defconst prolog-font-lock-keywords (purecopy
  71.   (list
  72.    (cons (concat
  73.       "[( \t]\\("
  74.       (mapconcat 'identity
  75.              '("write" "writeq" "nl" "is" "call" "read" "get" "get0"
  76.                "tell" "told" "open" "close" "format" "put"
  77.                "assert" "asserta" "assertz"
  78.                "retract" "retractall" "clause"
  79.                "record" "recorda" "abolish"
  80.                "setof" "bagof" "findall" "sort" "compare"
  81.                "var" "nonvar" "integer" "float"  "number" "ground"
  82.                "atom" "atomic" "simple" "callable" "compound"
  83.                "functor" "arg" "copy_term" "numbervars"
  84.                "atom_chars"  "number_chars" "atom_to_chars"
  85.                "length" "unix" "halt"
  86.                "op" "dynamic" "meta_predicate" "raise_exception"
  87.                "module" "ensure_loaded" "use_module"
  88.                "fail" "true"
  89.                "module_interface" "begin_module" "define_struct"
  90.                "import" "export" "global" "tool" "external"
  91.                "define_macro" "local" "library" "from"
  92.                )
  93.              "\\|")
  94.       "\\)[ .,\t\n()]")
  95.      1)
  96.    '("^[a-z][a-zA-Z0-9_]+"   0 font-lock-function-name-face)
  97. ;   '("[@!$#]"   0 font-lock-function-name-face)
  98.    '("!"   0 font-lock-function-name-face)
  99.    '("@"   0 font-lock-function-name-face)
  100.    '("<=>"   0 font-lock-function-name-face)
  101.    '("==>"   0 font-lock-function-name-face)
  102.    '(";"   0 font-lock-function-name-face)
  103.    '(":-" 0 font-lock-function-name-face)
  104.    '("\\[" 0 font-lock-keyword-face)
  105.    '("\\]" 0 font-lock-keyword-face)
  106.    '("|" 0 font-lock-keyword-face)
  107.    ))
  108.   "Additional expressions to highlight in Prolog mode.")
  109.  
  110. (if prolog-mode-syntax-table
  111.     ()
  112.   (let ((table (make-syntax-table)))
  113.     (modify-syntax-entry ?/  ". 14" table)
  114.     (modify-syntax-entry ?*  ". 23" table)
  115.     (modify-syntax-entry ?%  "< b"  table)
  116.     (modify-syntax-entry ?\n "> b"  table)
  117.     (modify-syntax-entry ?_  "w"  table)
  118.     (modify-syntax-entry ?\\ "\\" table)
  119.     (modify-syntax-entry ?\' "\"" table)
  120.     (modify-syntax-entry ?+  "." table)
  121.     (modify-syntax-entry ?-  "." table)
  122.     (modify-syntax-entry ?=  "." table)
  123.     (modify-syntax-entry ?<  "." table)
  124.     (modify-syntax-entry ?>  "." table)
  125.     (setq prolog-mode-syntax-table table)))
  126.  
  127. (define-abbrev-table 'prolog-mode-abbrev-table ())
  128.  
  129. (defun prolog-mode-variables ()
  130.   (set-syntax-table prolog-mode-syntax-table)
  131.   (setq local-abbrev-table prolog-mode-abbrev-table)
  132.   (make-local-variable 'paragraph-start)
  133.   (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
  134.   (make-local-variable 'paragraph-separate)
  135.   (setq paragraph-separate paragraph-start)
  136.   (make-local-variable 'paragraph-ignore-fill-prefix)
  137.   (setq paragraph-ignore-fill-prefix t)
  138.   (make-local-variable 'indent-line-function)
  139.   (setq indent-line-function 'prolog-indent-line)
  140.   (make-local-variable 'comment-start)
  141.   (setq comment-start "%")
  142.   (make-local-variable 'comment-start-skip)
  143.   (setq comment-start-skip "%+ *")
  144.   (make-local-variable 'comment-column)
  145.   (setq comment-column 48)
  146.   (make-local-variable 'comment-indent-function)
  147.   (setq comment-indent-function 'prolog-comment-indent))
  148.  
  149. (defun prolog-mode-commands (map)
  150.   (define-key map "\t" 'prolog-indent-line)
  151.   (define-key map "\e\C-x" 'prolog-consult-region))
  152.  
  153. (if prolog-mode-map
  154.     nil
  155.   (setq prolog-mode-map (make-sparse-keymap))
  156.   (prolog-mode-commands prolog-mode-map))
  157.  
  158. ;;;###autoload
  159. (defun prolog-mode ()
  160.   "Major mode for editing Prolog code for Prologs.
  161. Blank lines and `%%...' separate paragraphs.  `%'s start comments.
  162. Commands:
  163. \\{prolog-mode-map}
  164. Entry to this mode calls the value of `prolog-mode-hook'
  165. if that value is non-nil."
  166.   (interactive)
  167.   (kill-all-local-variables)
  168.   (use-local-map prolog-mode-map)
  169.   (setq major-mode 'prolog-mode)
  170.   (setq mode-name "Prolog")
  171.   (prolog-mode-variables)
  172.   (run-hooks 'prolog-mode-hook))
  173.  
  174. (defun prolog-indent-line (&optional whole-exp)
  175.   "Indent current line as Prolog code.
  176. With argument, indent any additional lines of the same clause
  177. rigidly along with this one (not yet)."
  178.   (interactive "p")
  179.   (let ((indent (prolog-indent-level))
  180.     (pos (- (point-max) (point))) beg)
  181.     (beginning-of-line)
  182.     (setq beg (point))
  183.     (skip-chars-forward " \t")
  184.     (if (zerop (- indent (current-column)))
  185.     nil
  186.       (delete-region beg (point))
  187.       (indent-to indent))
  188.     (if (> (- (point-max) pos) (point))
  189.     (goto-char (- (point-max) pos)))
  190.     ))
  191.  
  192. (defun prolog-indent-level ()
  193.   "Compute prolog indentation level."
  194.   (save-excursion
  195.     (beginning-of-line)
  196.     (skip-chars-forward " \t")
  197.     (cond
  198.      ((looking-at "%%%") 0)        ;Large comment starts
  199.      ((looking-at "%[^%]") comment-column) ;Small comment starts
  200.      ((bobp) 0)                ;Beginning of buffer
  201.      (t
  202.       (let ((empty t) ind more less)
  203.     (if (looking-at ")")
  204.         (setq less t)        ;Find close
  205.       (setq less nil))
  206.     ;; See previous indentation
  207.     (while empty
  208.       (forward-line -1)
  209.       (beginning-of-line)
  210.        (if (bobp)
  211.            (setq empty nil)
  212.          (skip-chars-forward " \t")
  213.          (if (not (or (looking-at "%[^%]") (looking-at "\n")))
  214.          (setq empty nil))))
  215.      (if (bobp)
  216.          (setq ind 0)        ;Beginning of buffer
  217.       (setq ind (current-column)))    ;Beginning of clause
  218.     ;; See its beginning
  219.     (if (looking-at "%%[^%]")
  220.         ind
  221.       ;; Real prolog code
  222.       (if (looking-at "(")
  223.           (setq more t)        ;Find open
  224.         (setq more nil))
  225.       ;; See its tail
  226.       (end-of-prolog-clause)
  227.       (or (bobp) (forward-char -1))
  228.       (cond ((looking-at "[,(;>]")
  229.          (if (and more (looking-at "[^,]"))
  230.              (+ ind prolog-indent-width) ;More indentation
  231.            (max tab-width ind))) ;Same indentation
  232.         ((looking-at "-") tab-width) ;TAB
  233.         ((or less (looking-at "[^.]"))
  234.          (max (- ind prolog-indent-width) 0)) ;Less indentation
  235.         (t 0))            ;No indentation
  236.       )))
  237.      )))
  238.  
  239. (defun end-of-prolog-clause ()
  240.   "Go to end of clause in this line."
  241.   (beginning-of-line 1)
  242.   (let* ((eolpos (save-excursion (end-of-line) (point))))
  243.     (if (re-search-forward comment-start-skip eolpos 'move)
  244.     (goto-char (match-beginning 0)))
  245.     (skip-chars-backward " \t")))
  246.  
  247. (defun prolog-comment-indent ()
  248.   "Compute prolog comment indentation."
  249.   (cond ((looking-at "%%%") 0)
  250.     ((looking-at "%%") (prolog-indent-level))
  251.     (t
  252.      (save-excursion
  253.            (skip-chars-backward " \t")
  254.            ;; Insert one space at least, except at left margin.
  255.            (max (+ (current-column) (if (bolp) 0 1))
  256.             comment-column)))
  257.     ))
  258.  
  259.  
  260. ;;;
  261. ;;; Inferior prolog mode
  262. ;;;
  263. (defvar inferior-prolog-mode-map nil)
  264.  
  265. ;;;###autoload
  266. (defun inferior-prolog-mode ()
  267.   "Major mode for interacting with an inferior Prolog process.
  268.  
  269. The following commands are available:
  270. \\{inferior-prolog-mode-map}
  271.  
  272. Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
  273. if that value is non-nil.  Likewise with the value of `comint-mode-hook'.
  274. `prolog-mode-hook' is called after `comint-mode-hook'.
  275.  
  276. You can send text to the inferior Prolog from other buffers
  277. using the commands `send-region', `send-string' and \\[prolog-consult-region].
  278.  
  279. Commands:
  280. Tab indents for Prolog; with argument, shifts rest
  281.  of expression rigidly with the current line.
  282. Paragraphs are separated only by blank lines and '%%'.
  283. '%'s start comments.
  284.  
  285. Return at end of buffer sends line as input.
  286. Return not at end copies rest of line to end and sends it.
  287. \\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
  288. \\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
  289. \\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
  290.   (interactive)
  291.   (require 'comint)
  292.   (comint-mode)
  293.   (setq major-mode 'inferior-prolog-mode
  294.     mode-name "Inferior Prolog"
  295.     comint-prompt-regexp "^| [ ?][- ] *")
  296.   (prolog-mode-variables)
  297.   (if inferior-prolog-mode-map nil
  298.     (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
  299.     (prolog-mode-commands inferior-prolog-mode-map))
  300.   (use-local-map inferior-prolog-mode-map)
  301.   (run-hooks 'prolog-mode-hook))
  302.  
  303. ;;;###autoload
  304. (defun run-prolog ()
  305.   "Run an inferior Prolog process, input and output via buffer *prolog*."
  306.   (interactive)
  307.   (require 'comint)
  308.   (switch-to-buffer (make-comint "prolog" prolog-program-name))
  309.   (inferior-prolog-mode))
  310.  
  311. (defun prolog-consult-region (compile beg end)
  312.   "Send the region to the Prolog process made by \"M-x run-prolog\".
  313. If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
  314.   (interactive "P\nr")
  315.   (save-excursion
  316.     (if compile
  317.     (send-string "prolog" prolog-compile-string)
  318.       (send-string "prolog" prolog-consult-string))
  319.     (send-region "prolog" beg end)
  320.     (send-string "prolog" "\n")        ;May be unnecessary
  321.     (if prolog-eof-string
  322.     (send-string "prolog" prolog-eof-string)
  323.       (process-send-eof "prolog")))) ;Send eof to prolog process.
  324.  
  325. (defun prolog-consult-region-and-go (compile beg end)
  326.   "Send the region to the inferior Prolog, and switch to *prolog* buffer.
  327. If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
  328.   (interactive "P\nr")
  329.   (prolog-consult-region compile beg end)
  330.   (switch-to-buffer "*prolog*"))
  331.  
  332. ;;; prolog.el ends here
  333.